----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    09:57:12 05/23/2012 
-- Design Name: 
-- Module Name:    ASIC_TARGET4 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--library UNISIM;
--use UNISIM.VComponents.all;

entity ASIC_TARGET4 is
	generic (
		constant BIT_WIDTH : integer := 363		--Total 363 bits for TARGET4 registers.
			);
	port (
		CLK 				:  in  	STD_LOGIC;
		RESET				:	IN		STD_LOGIC;
		UPDATE			:	IN		STD_LOGIC;
		REG_DATA			:	IN		STD_LOGIC_VECTOR(BIT_WIDTH-1 DOWNTO 0);
		
		SCLK 				:  out 	STD_LOGIC;
		SIN 				:  out 	STD_LOGIC;
		REGCLR			:	OUT	STD_LOGIC;
		PCLK 				:  out 	STD_LOGIC
	);
end ASIC_TARGET4;

architecture Behavioral of ASIC_TARGET4 is
	type STATE_TYPE is 
		(IDLE,
		UPDATE_DACs
		);

signal state 				: STATE_TYPE := IDLE;
signal toggle				: std_logic := '1';
signal step_cnt			: integer := 0;	--count the steps when sending the serial  
SIGNAL cnt					: integer := 0;	--count 363 bits when clocked in data serially
begin
	
	SERIAL_CONFIG_DAC_TARGET4 : PROCESS(CLK, RESET, UPDATE)
		--variable		cnt	: integer range 0 to BIT_WIDTH := 0;
	
	BEGIN
		------------------------------------------------------------
		IF RESET = '1' THEN
			REGCLR	<= '1';	--RESET INTERNAL REGISTERS
			SCLK		<= '0';
			SIN		<= '0';
			PCLK 		<= '0';
			toggle 	<= '0';
			cnt 		<= 0;
			step_cnt <= 0;
		ELSIF RISING_EDGE(CLK) THEN
			REGCLR	<= '0';
			------------------------------------------------------------
			CASE STATE IS
				--------------------------------
				WHEN IDLE =>
					SCLK		<= '0';
					SIN		<= '0';
					PCLK 		<= '0';
					toggle 	<= '0';
					cnt 		<= 0;
					step_cnt <= 0;
					if UPDATE = '1' then
						state <= UPDATE_DACs;
					else
						state <= IDLE;
					end if;
				--------------------------------
				WHEN UPDATE_DACs =>
					if cnt < BIT_WIDTH then
						-----------------------------------------------------------------------------------
						--Fast version(2 steps). not sure if it works. "Vdly" voltage measurements are not stable during testing.
--						if toggle = '0' then	--"SIN", whose data is advanced on the rising edge of the "SCLK".
--							SCLK	<= '0';
--							--SIN	<= REG_DATA(cnt);	--SLB is sent as "cnt" increasing.
--							toggle <= '1';
--						else
--							SCLK	<= '1';
--							SIN	<= REG_DATA(cnt);
--							toggle <= '0';
--							cnt <= cnt + 1;							
--						end if;
						-----------------------------------------------------------------------------------
						--slower version(3 steps)
						if step_cnt = 0 then 
							SCLK <= '0';
							step_cnt <= step_cnt + 1;
						elsif step_cnt = 1 then
							SIN <= REG_DATA(cnt);	--SLB is sent first as "cnt" increasing.
							step_cnt <= step_cnt + 1;
						else
							SCLK <= '1';
							cnt <= cnt + 1;
							step_cnt <= 0;
						end if;
						
					else	--after 363 bits are clocked in
						SCLK <= '0';
						PCLK <= '1';	--update the actual control registers after all values have been serially loaded.
						state <= IDLE;
						cnt <= 0;
						step_cnt <= 0;
						
					end if;
				--------------------------------
				WHEN OTHERS =>
					state <= IDLE;
			END CASE;
			------------------------------------------------------------
		END IF;
		------------------------------------------------------------
	
	END PROCESS SERIAL_CONFIG_DAC_TARGET4;
	
	

end Behavioral;

